﻿package net.wangit.jdbc.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public final class GetGeneratedKeysUtil {

	private static final int RETURN_GENERATED_KEYS;
	private static final Method PREPARE_STATEMENT_METHOD;
	private static final Method GET_GENERATED_KEYS_METHOD;

	private GetGeneratedKeysUtil() {
	}

	public static PreparedStatement prepareStatement(Connection conn, String sql)
			throws SQLException {
		try {
			Object args[] = { sql, new Integer(RETURN_GENERATED_KEYS) };
			return (PreparedStatement) PREPARE_STATEMENT_METHOD.invoke(conn,
					args);
		} catch (InvocationTargetException ite) {
			if (ite.getTargetException() instanceof SQLException)
				throw (SQLException) ite.getTargetException();
			if (ite.getTargetException() instanceof RuntimeException)
				throw (RuntimeException) ite.getTargetException();
			else
				throw new RuntimeException("InvocationTargetException", ite);
		} catch (IllegalAccessException iae) {
			throw new RuntimeException("IllegalAccessException", iae);
		}
	}

	public static ResultSet getGeneratedKey(PreparedStatement ps)
			throws SQLException {
		try {
			return (ResultSet) GET_GENERATED_KEYS_METHOD.invoke(ps);
		} catch (InvocationTargetException ite) {
			if (ite.getTargetException() instanceof SQLException)
				throw (SQLException) ite.getTargetException();
			if (ite.getTargetException() instanceof RuntimeException)
				throw (RuntimeException) ite.getTargetException();
			else
				throw new RuntimeException("InvocationTargetException", ite);
		} catch (IllegalAccessException iae) {
			throw new RuntimeException("IllegalAccessException", iae);
		}
	}

	static {
		try {
			RETURN_GENERATED_KEYS = java.sql.Statement.class.getDeclaredField(
					"RETURN_GENERATED_KEYS").getInt(
					java.sql.PreparedStatement.RETURN_GENERATED_KEYS);
			PREPARE_STATEMENT_METHOD = java.sql.Connection.class.getMethod(
					"prepareStatement", new Class[] { java.lang.String.class,
							Integer.TYPE });
			GET_GENERATED_KEYS_METHOD = java.sql.Statement.class
					.getDeclaredMethod("getGeneratedKeys");
		} catch (Exception e) {
			throw new RuntimeException(
					"could not initialize getGeneratedKeys() support", e);
		}
	}
}
